package com.mtw.bbs.common.redisBase.impl;

import com.mtw.bbs.common.core.security.AccessLimitService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class RedisAccessLimitServiceI implements AccessLimitService {

    @Resource
    private Redisson redisson;

    /**
     * 锁住时的key前缀
     */
    public static final String LOCK_PREFIX = "limitLock:";


    /**
     * 单位 秒
     */
    public static final RateIntervalUnit seconds = RateIntervalUnit.SECONDS;



    /**
     * 判断某用户访问某接口是否已经被禁用/是否需要禁用
     *
     * @param second            多长时间  单位/秒
     * @param maxTime           最大访问次数
     * @param applicationName   应用名称
     * @param xid               访问者id
     * @param uri               访问的uri
     * @return ture为需要禁用
     */
    @Override
    public boolean isAcquire(long second, long maxTime,String applicationName, String xid, String uri) {

        String key = LOCK_PREFIX + applicationName + "_" + xid + "_" + uri;
        log.info("设置限流锁key={}", key);
        RRateLimiter rateLimiter = this.redisson.getRateLimiter(key);
        if (!rateLimiter.isExists()) {

            log.info("设置流量,rate={},rateInterval={},rateIntervalUnit={}", maxTime, second, seconds);
            rateLimiter.trySetRate(RateType.OVERALL, maxTime, second, seconds);
            //设置一个过期时间，避免key一直存在浪费内存，这里设置为延长5分钟
            long millis = seconds.toMillis(second);
            this.redisson.getBucket(key).expire(Long.sum(2 * 1000 * 60, millis), TimeUnit.MILLISECONDS);
        }
        return rateLimiter.tryAcquire(1);
    }


}
